#include <func.h>

#define DEBUG

int main(int argc,char *argv[])
{
    ARGS_CHECK(argc,3);
    int socketFd;
    //初始化一个socket，有一个缓冲区
    socketFd=socket(AF_INET,SOCK_STREAM,0);
    ERROR_CHECK(socketFd,-1,"socket");
    printf("socketFd=%d\n",socketFd);
    struct sockaddr_in ser;
    bzero(&ser,sizeof(ser));
    ser.sin_family=AF_INET;
    ser.sin_port=htons(atoi(argv[2]));
    ser.sin_addr.s_addr=inet_addr(argv[1]);
    int ret;
    ret=bind(socketFd,(struct sockaddr *)&ser,sizeof(struct sockaddr));
    ERROR_CHECK(ret,-1,"bind");
    printf("server listening...\n");
    listen(socketFd,10);//端口激活


    int new_fd;//用来保存新建连接
    int max_of_fd = 3;//记录链接的描述符的最大值，接收数据的时候用来遍历 
    
    struct sockaddr_in client;//从内核拿出对方的socket信息
    char buf[1000]={0};
    fd_set rdset,tmpset;//永久记录我们要监控的描述符
    int readyFdNum;
    FD_ZERO(&tmpset);
    FD_SET(socketFd,&tmpset);//监控socketFd
    while(1)
    {
        FD_ZERO(&rdset);
        memcpy(&rdset,&tmpset,sizeof(fd_set));//每次更新rdset
        readyFdNum=select(14,&rdset,NULL,NULL,NULL);
        if(readyFdNum)
        {
            if(FD_ISSET(socketFd,&rdset))
            {
                //有人连接
                bzero(&client,sizeof(client));
                socklen_t len=sizeof(client);
                new_fd=accept(socketFd,(struct sockaddr *)&client,&len);
                ERROR_CHECK(new_fd,-1,"accept");
                printf("user connected !client ip=%s,client port=%d\n",\
                       inet_ntoa(client.sin_addr),ntohs(client.sin_port));
                FD_SET(new_fd,&tmpset);
                printf("new users fd: %d ",new_fd);
                max_of_fd++;
                printf("pepole in room: %d\n",max_of_fd-3);
            }
            else
            {
                printf("recv message:\n");
                bzero(buf,sizeof(buf));
                for(int i =4;i<=max_of_fd;++i )
                {
                    if(FD_ISSET(i,&rdset))
                    {
                        ret=recv(i,buf,sizeof(buf),0);
                        if(!ret)
                        {
                            //断开连接处理
                            printf("user disconnected!\n");
#ifdef DEBUG              
                            printf("\nbefore change: old(max_of_fd):%d,new:%d\n",max_of_fd,i);
#endif 
                            dup2(max_of_fd,i);//前边是old 后边是new！
                            
                            close(max_of_fd);
                            FD_CLR(max_of_fd,&tmpset);//断开后不再监控对应描述符
                            max_of_fd--;
#ifdef DEBUG
                            printf("after change: max_of_fd:%d\n",max_of_fd);
#endif 
                            continue;
                        }
                        for(int j = 4;j<=max_of_fd;++j)
                        {
                            if(j!=i)
                            {
                                send(j,buf,strlen(buf),0);
                            }
                        }
                        printf("%s\n",buf);
                    }
                }
            }
        }
    }
    
    close(new_fd);
    close(socketFd);
    return 0;
}

